const Koa = require("koa");
const koaStaticCache = require("koa-static-cache");
const koaRouter = require("koa-router");
const config = require("./config");
const koaBody = require("koa-body");
const databaseMiddleware = require("./middlewares/database");
const tplMiddleware = require("./middlewares/tpl");
const userMiddleWare = require("./middlewares/user");
const authMiddleWare = require("./middlewares/auth");

const server = new Koa();
const router = new koaRouter();

server.keys = config.user.cookieSignKey;
server.use(userMiddleWare());

server.use(koaStaticCache(config.static));
server.use(databaseMiddleware(config.database));
server.use(tplMiddleware(config.template));

router.get("/", async (ctx, next) => {
    let categoryService = ctx.state.services.category;
    let itemService = ctx.state.services.item;

    let categories = await categoryService.getCategories();
    let categoryItems = [];
    for (let i = 0; i < categories.length; i++) {
        let category = categories[i];
        let { items } = await itemService.getItems(category.id);
        categoryItems.push({
            categoryId: category.id,
            categoryName: category.name,
            items,
        });
    }

    ctx.render("index.html", {
        categories,
        categoryItems,
    });
});

router.get("/list/:categoryId", async (ctx, next) => {
    let { categoryId } = ctx.params;
    let { page, limit } = ctx.query;
    categoryId = Number(categoryId);
    page = Number(page) || 1;
    limit = Number(limit) || 4;

    let categoryService = ctx.state.services.category;
    let categories = await categoryService.getCategories();
    let category = categories.find((c) => c.id == categoryId);
    let itemService = ctx.state.services.item;
    let items = await itemService.getItems(categoryId, page, limit);

    ctx.render("list.html", {
        categories,
        category,
        items,
    });
});

router.get("/detail/:itemId", async (ctx, next) => {
    let { itemId } = ctx.params;
    let { page, limit } = ctx.query;
    itemId = Number(itemId);
    page = Number(page) || 1;
    limit = Number(limit) || 4;

    let categoryService = ctx.state.services.category;
    let categories = await categoryService.getCategories();
    let itemService = ctx.state.services.item;

    let item = await itemService.getItem(itemId);
    let category = categories.find((c) => c.id == item.categoryId);

    let commentService = ctx.state.services.comment;
    let comments = await commentService.getComments(item.id, page, limit);

    comments.comments = comments.comments.map((comment) => {
        let d = new Date(comment.createdAt);
        return {
            ...comment,
            createAtByDate: `${d.getFullYear()}年${
                d.getMonth() + 1
            }月${d.getDate()}日`,
        };
    });
    ctx.render("detail.html", {
        categories,
        category,
        item,
        comments,
    });
});

router.get("/signup", async (ctx, next) => {
    let categoryService = ctx.state.services.category;
    let categories = await categoryService.getCategories();

    ctx.render("signup.html", {
        categories,
    });
});
router.post("/signup", koaBody(), async (ctx, next) => {
    let { username, password, repassword } = ctx.request.body;
    let categoryService = ctx.state.services.category;
    let categories = await categoryService.getCategories();

    if (!username || !password || !repassword) {
        return ctx.render("message.html", {
            categories,
            message: "注册失败",
            response: ["注册信息不正确"],
            url: "javascript:window.history.back();",
        });
    }

    if (password != repassword) {
        return ctx.render("message.html", {
            categories,
            message: "注册失败",
            response: ["两次密码不一致"],
            url: "javascript:window.history.back();",
        });
    }

    let userService = ctx.state.services.user;
    let user = await userService.getUserByUsername(username);
    if (user) {
        return ctx.render("message.html", {
            categories,
            message: "注册失败",
            response: ["用户已经被注册"],
            url: "javascript:window.history.back();",
        });
    }
    let loginUser = await userService.signup(username, password);
    if (!loginUser) {
        return ctx.render("message.html", {
            categories,
            message: "注册失败",
            response: [""],
            url: "javascript:window.history.back();",
        });
    }

    ctx.render("message.html", {
        categories,
        message: "注册成功",
        response: "",
        url: "/signin",
    });
});
router.get("/signin", async (ctx, next) => {
    ctx.render("signin.html", {});
});
router.post("/signin", koaBody(), async (ctx, next) => {
    let { username, password } = ctx.request.body;
    let categoryService = ctx.state.services.category;
    let categories = await categoryService.getCategories();

    console.log(username, password);
    if (!username || !password) {
        return ctx.render("message.html", {
            categories,
            message: "登录失败",
            response: ["登录信息不正确"],
            url: "javascript:window.history.back();",
        });
    }

    let userService = ctx.state.services.user;
    let user = await userService.getUserByUsername(username);
    if (!user || user.password != password) {
        return ctx.render("message.html", {
            categories,
            message: "登录失败",
            response: ["用户不存在或密码错误"],
            url: "javascript:window.history.back();",
        });
    }

    ctx.cookies.set(
        "user",
        JSON.stringify({
            id: user.id,
            username: user.username,
        }),
        {
            signed: true,
        }
    );

    ctx.render("message.html", {
        categories,
        message: "登录成功",
        url: "/",
    });
});
router.get("/user", authMiddleWare(), async (ctx, next) => {
    let categoryService = ctx.state.services.category;
    let categories = await categoryService.getCategories();
    let userService = ctx.state.services.user;
    let user = await userService.getUserByUsername(ctx.state.user.username);
    ctx.render("user.html", {
        user: { ...ctx.state.user, avatar: user.avatar },
        categories,
    });
});
router.post(
    "/avatar",
    koaBody({
        multipart: true,
        formidable: {
            uploadDir: "./public/avatar",
            keepExtensions: true,
        },
    }),
    async (ctx, next) => {
        let avatar = ctx.request.files.avatar;
        let userService = ctx.state.services.user;
        let res = await userService.postAvatar(ctx.state.user.id, avatar.path);
        ctx.redirect("/user");
    }
);
router.post("/comment", authMiddleWare(), koaBody(), async (ctx, next) => {
    let { itemId, content } = ctx.request.body;

    let categoryService = ctx.state.services.category;
    let categories = await categoryService.getCategories();

    if (!content) {
        return ctx.render("message.html", {
            user: ctx.state.user,
            categories,
            message: "评论失败",
            response: ["内容不能为空"],
            url: "javascript:window.history.back();",
        });
    }

    let commentService = ctx.state.services.comment;
    let commentId = await commentService.postComment(
        itemId,
        ctx.state.user.id,
        content
    );

    if (content) {
        return ctx.render("message.html", {
            user: ctx.state.user,
            categories,
            message: "评论成功",
            response: [""],
            url: `/detail/${itemId}`,
        });
    }
});

server.use(router.routes());
server.listen(config.server.port, () => {
    console.log("server is running");
});
